/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package alcatelparser.modules;

import alcatelparser.errors.ParseFailedException;
import alcatelparser.tags.BodyTag;
import alcatelparser.tags.CallDurationTag;
import alcatelparser.tags.ITagParser;
import alcatelparser.tags.MarketSpecificRecordType1;
import alcatelparser.tags.MarketSpecificRecordType2;
import alcatelparser.tags.MarketSpecificRecordType3;
import alcatelparser.tags.MarketSpecificRecordType4;
import alcatelparser.tags.MarketSpecificRecordType5;
import alcatelparser.tags.MarketSpecificRecordsTypeTag;
import alcatelparser.tags.ParticipantInfoTag;
import alcatelparser.tags.RecordExtensionsTag;
import alcatelparser.tags.StartTimeStampTag;
import alcatelparser.tags.TrunkGroupIncomingTag;
import alcatelparser.tags.TrunkGroupOutgoingTag;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

/**
 *
 * @author geniuz
 */
public class Parser
{
    Statement stmt;
    Connection db;
    public Parser() throws ClassNotFoundException, SQLException
    {
        String username = "pg_admin";
        String password = "[jxe100,jxtrgbdf";
        Class.forName("org.postgresql.Driver"); //load the driver
        db = DriverManager.getConnection("jdbc:postgresql://192.168.20.16:5432/test",username,password); //connect to the db
        DatabaseMetaData  dbmd = db.getMetaData(); //get MetaData to confirm connection
        stmt = db.createStatement();
        _stopProcessIndicator = false;
        _errors = 0;
        Result = "";
        _tFactory = new TagFactory();
        Env.getEnv().put(I.I(7894), _tFactory);
    }

    public final void startParse(File file) throws FileNotFoundException, IOException, ParseFailedException
    {
        _sourceFileSize = file.length();
        //_pProcessor.setSourceFileSize(_sourceFileSize);
        PreparseAnalyzer preparseanalyzer = new PreparseAnalyzer(_tFactory);
        //System.out.print("Factory gened\n");
        parseConvertedFile(preparseanalyzer.preparseAnalyze(file));
    }
    FileWriter fw;
    private void parseConvertedFile(File file) throws IOException
    {
        //System.out.print(file.getAbsolutePath()+"\n");
        ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
        try {
            //System.out.print("File readed\n"+file.getAbsolutePath()+"\n");
            readFile(file, bytearrayoutputstream);
            
        } catch (FileNotFoundException ex) {
            System.out.print("err1\n");
            System.out.print(ex.getMessage());
        } catch (IOException ex) {
            System.out.print("err2\n");
            System.out.print(ex.getMessage());
        }
        //*_pProcessor.setParsedFileSize(_array.length);
        //_pDialog.setProcessStatusText(I.I(7643));
        //BuilderFactory.getBuilder().writeOverAllHeader(outputfile);
        validateArray();
        fw=new FileWriter("tmp.tmp");
        

        _tagStart = 0;
        sb=new StringBuilder("select * from " +ApplicationSettings.getInstance().getProperty("dbfunc") +"(");
        //quer = "INSERT INTO s12_logs(record_type, ans_time, calling_number, called_number, outtrunk, intrunk, duration, traf_type, traf_code) values ";
        System.out.print("parsing");
        field_count = 0;
        sb.append("'"+file.getName()+"','{");
        parseFile();
        fw.close();
        try {
            String query = sb.toString();
            query = query.substring(0, query.length()-2);
            query = query + "}'::character varying[])";
            FileWriter fw=new FileWriter("tmp.tmp");
            fw.write(query);
            fw.close();
            stmt.close();
            db.close();
        } catch (SQLException ex) {
            System.out.println(ex.getMessage());
        }
        try
        {
            finalyzeParseProcess(bytearrayoutputstream);
            deleteConvertedFile(file);
        }
        catch(IOException ioexception)
        {
            //LOG.error(ioexception);
        }
      
        
    }

    private void deleteConvertedFile(File file)
    {
        if(file != null && file.getAbsolutePath().endsWith(I.I(7609)))
            file.delete();
    }

    private void parseFile()
    {
        boolean flag = false;
label0:
        do
        {
            do
            {
                if(_curPosition >= _array.length)
                    break label0;
                if(_tFactory.isRecordFinished(_array, _curPosition))
                {
                    finishRecord();
                    if(AlgoUtil.isLastTagsZero(_array, _curPosition))
                        break label0;
                }
                if(_stopProcessIndicator)
                    break label0;
                parseTag();
            } while(!_tFactory.isRecordFinished(_array, _curPosition));
            finishRecord();
            flag = true;
        } while(!AlgoUtil.isLastTagsZero(_array, _curPosition));
        if(!flag)
            finishRecord();
    }

    private void validateArray()
    {
        if(_array.length == 0)
        {
            
        }
        else
            return;
    }

    private void readFile(File file, ByteArrayOutputStream bytearrayoutputstream) throws FileNotFoundException, IOException
    {
        FileInputStream fileinputstream = new FileInputStream(file);
        _array = new int[fileinputstream.available()];
        int j = 0;
        int k = 0;
        do
        {
            int i;
            if((i = fileinputstream.read()) == -1 || _stopProcessIndicator)
                break;
            bytearrayoutputstream.write(i);
            _array[j] = i;
            j++;
            if(++k > 1000)
            {
                k = 0;
            }
        } while(true);
    }
    
    private void finishRecord()
    {
        BuilderFactory.getBuilder().buildHeader(_array, _tagStart, _curPosition - 1);
        _tagStart = _curPosition;
        _tFactory.releaseResources();
        _currentRecord++;
        //if (_currentRecord==432){
        //    System.out.println();
        //}
        field_count=0;
        Result = Result.substring(0,Result.length()-2);
        //try {
            //fw.write(Result + "\n");
        //} catch (IOException ex) {
            //Logger.getLogger(Parser.class.getName()).log(Level.SEVERE, null, ex);
        //}
        
        //String query = quer + "(" + Result + ")";
        sb.append(Result+",\n");
        Result = "";
        /*
        try {
            int x = stmt.executeUpdate(query);
        } catch (SQLException ex) {
            System.out.println(ex.getMessage());
            System.out.println(_currentRecord);
        }*/
    }

    private void finalyzeParseProcess(ByteArrayOutputStream bytearrayoutputstream) throws IOException
    {
        BuilderFactory.getBuilder().writeSummary(_errors);
        _tFactory.releaseResources();
        //_wroteRecords = BuilderFactory.getBuilder().getRecordWroteAmount();
        _wroteSize = BuilderFactory.getBuilder().getWroteSize();
        BuilderFactory.getBuilder().releaseContent();
        System.gc();
        bytearrayoutputstream.flush();
        _array = null;
    }
    private String Result;
    private String quer;
    private StringBuilder sb;
    private void parseTag()
    {
        int i = AlgoUtil.getTag(_array, _curPosition);
        _curPosition += AlgoUtil.getTagIteration();
        ITagParser itagparser = _tFactory.getTag(i);
        if(itagparser != null)
        {
            itagparser.parseTag(_array, _curPosition);            
            if (itagparser instanceof StartTimeStampTag || itagparser instanceof ParticipantInfoTag || itagparser instanceof CallDurationTag || itagparser instanceof RecordExtensionsTag || itagparser instanceof TrunkGroupIncomingTag || itagparser instanceof TrunkGroupOutgoingTag)
            {
                if (itagparser instanceof CallDurationTag && field_count==4){
                    Result += "~";
                }
                if (itagparser instanceof CallDurationTag && field_count==3){
                    Result += "~~";
                }
                if (itagparser instanceof RecordExtensionsTag && Result.startsWith("3")){
                    Result += itagparser.GetResult();
                }
                else 
                {
                    Result += itagparser.GetResult();
                }
                if (itagparser instanceof ParticipantInfoTag && Result.startsWith("3")){
                    Result += "~~~0~";
                }
                
                field_count++;
            }
            if (itagparser instanceof MarketSpecificRecordsTypeTag){
                field_count++;
                if (itagparser instanceof MarketSpecificRecordType1){
                    Result += "1~";
                }
                else if (itagparser instanceof MarketSpecificRecordType2){
                    Result += "2~";
                }
                else if (itagparser instanceof MarketSpecificRecordType3){
                    Result += "3~";
                }
                else if (itagparser instanceof MarketSpecificRecordType4){
                    Result += "4~";
                }
                else if (itagparser instanceof MarketSpecificRecordType5){
                    Result += "5~";
                }
                
            }
            _curPosition += itagparser.getReadBytesCount();
            BuilderFactory.getBuilder().tagParseEnd(itagparser);
            if(itagparser instanceof BodyTag)
            {
                BuilderFactory.getBuilder().notifyHeaderEnd(_tagStart, _curPosition - 1, _array);
                _tagStart = _curPosition;
            }
        } else
        {
            //LOG.error(I.I(5351));
            _curPosition++;
        }
    }
    public final void stopParseProcess()
    {
        _stopProcessIndicator = true;
    }

    public long getWroteRecords()
    {
        return _currentRecord;
    }

    public final long getWroteSize()
    {
        return _wroteSize;
    }

    private int _tagStart, field_count;
    private boolean _stopProcessIndicator;
    private long _wroteSize;
    private long _sourceFileSize;
    private int _array[];
    private int _curPosition;
    public long _currentRecord;
    private TagFactory _tFactory;
    private int _errors;
}
